package com.qiangesoft.calendar.mxnzp;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qiangesoft.calendar.entity.CalendarConfig;
import com.qiangesoft.calendar.mxnzp.model.CalendarConfigDTO;
import com.qiangesoft.calendar.mxnzp.model.MxnzpCalendarDTO;
import com.qiangesoft.calendar.mxnzp.model.MxnzpResponseData;
import com.qiangesoft.calendar.service.CalendarConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * mxnpz数据拉取 定时器执行者
 *
 * @author qiangesoft
 * @date 2023-09-29
 */
@Slf4j
@Component
public class MxnzpCalendarTask {

    private static String URL = "https://www.mxnzp.com/api/holiday/list/year/%d?ignoreHoliday=false&app_id=tldkn1hkkoofques&app_secret=kV9qgeRJ5baZworKApsWVbHS3hNxndYZ";

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private CalendarConfigService calendarConfigService;

    /**
     * 国家一般当年10月底发布下一年度的节假日安排
     */
    @Scheduled(cron = "0 0 10 * * ?")
    public void action() {
        LocalDate today = LocalDate.now();
        // 从11月开始拉取下一年的数据
        int year = today.getYear();
        if (today.getMonthValue() > 10) {
            year = year + 1;
        }

        log.info("Mxnzp data pull {}year start======================>", year);

        LambdaQueryWrapper<CalendarConfig> countQueryWrapper = new LambdaQueryWrapper<>();
        countQueryWrapper.eq(CalendarConfig::getYear, year)
                .eq(CalendarConfig::getPullFlag, true);
        long count = calendarConfigService.count(countQueryWrapper);
        if (count > 0) {
            log.info("Mxnzp data already update, do nothing!");
            return;
        }

        ResponseEntity<MxnzpResponseData> responseEntity = restTemplate.getForEntity(String.format(URL, year), MxnzpResponseData.class);
        HttpStatus statusCode = responseEntity.getStatusCode();
        if (!HttpStatus.OK.equals(statusCode)) {
            log.info("Mxnzp data pull fail!");
            return;
        }

        MxnzpResponseData responseData = responseEntity.getBody();
        if (!responseData.getCode().equals(1)) {
            log.info("Mxnzp data pull fail!");
            return;
        }

        List<MxnzpCalendarDTO> data = responseData.getData();
        if (CollectionUtils.isEmpty(data)) {
            log.info("Mxnzp data pull is empty!");
            return;
        }

        LambdaQueryWrapper<CalendarConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CalendarConfig::getYear, year);
        List<CalendarConfig> calendarConfigList = calendarConfigService.list(queryWrapper);
        Map<String, CalendarConfig> configMap = calendarConfigList.stream().collect(Collectors.toMap(CalendarConfig::getDate, calendarConfig -> calendarConfig));

        List<CalendarConfig> newConfigList = new ArrayList<>();
        List<CalendarConfig> updateConfigList = new ArrayList<>();
        for (MxnzpCalendarDTO monthData : data) {
            List<CalendarConfigDTO> days = monthData.getDays();
            for (CalendarConfigDTO day : days) {
                CalendarConfig calendarConfig = configMap.get(day.getDate());
                if (calendarConfig == null) {
                    calendarConfig = new CalendarConfig();
                    calendarConfig.setYear(monthData.getYear());
                    calendarConfig.setMonth(monthData.getMonth());
                    calendarConfig.setDate(day.getDate());
                    calendarConfig.setType(day.getType());
                    calendarConfig.setTypeDes(day.getTypeDes());
                    calendarConfig.setWeekDay(day.getWeekDay());
                    calendarConfig.setDayOfYear(day.getDayOfYear());
                    calendarConfig.setWeekOfYear(day.getWeekOfYear());
                    calendarConfig.setIndexWorkDayOfMonth(day.getIndexWorkDayOfMonth());
                    calendarConfig.setLunarCalendar(day.getLunarCalendar());
                    calendarConfig.setSolarTerms(day.getSolarTerms());
                    calendarConfig.setYearTips(day.getYearTips());
                    calendarConfig.setChineseZodiac(day.getChineseZodiac());
                    calendarConfig.setConstellation(day.getConstellation());
                    calendarConfig.setSuit(day.getSuit());
                    calendarConfig.setAvoid(day.getAvoid());
                    calendarConfig.setPullFlag(true);

                    newConfigList.add(calendarConfig);
                } else {
                    calendarConfig.setType(day.getType());
                    calendarConfig.setTypeDes(day.getTypeDes());
                    calendarConfig.setWeekDay(day.getWeekDay());
                    calendarConfig.setDayOfYear(day.getDayOfYear());
                    calendarConfig.setWeekOfYear(day.getWeekOfYear());
                    calendarConfig.setIndexWorkDayOfMonth(day.getIndexWorkDayOfMonth());
                    calendarConfig.setLunarCalendar(day.getLunarCalendar());
                    calendarConfig.setSolarTerms(day.getSolarTerms());
                    calendarConfig.setYearTips(day.getYearTips());
                    calendarConfig.setChineseZodiac(day.getChineseZodiac());
                    calendarConfig.setConstellation(day.getConstellation());
                    calendarConfig.setSuit(day.getSuit());
                    calendarConfig.setAvoid(day.getAvoid());
                    calendarConfig.setPullFlag(true);

                    updateConfigList.add(calendarConfig);
                }
            }
        }

        if (!CollectionUtils.isEmpty(newConfigList)) {
            calendarConfigService.saveBatch(newConfigList);
        }
        if (!CollectionUtils.isEmpty(updateConfigList)) {
            calendarConfigService.updateBatchById(updateConfigList);
        }

        log.info("Mxnzp data {}year updated<========================", year);
    }
}
